<?php
	/**
	*后台管理用户登录模块
	**/
	class Login {
		private static $object;

		//单例模式 start
		private function __construct()
		{
		}

		public static function newClass()
		{
		    if(!(self::$object instanceof self))
		    {
		        self::$object = new self;
		    }
		    return self::$object;
		}
		//单例模式 end
		// 登录
		public function loginIn($model, $action, $jsonObj){
			global $db, $session, $databaseInfo;
			if(($model=="login") && ($action=="loginin")){
				$verifyCode = strtolower($jsonObj->verifyCode);
				$name = $jsonObj->name;
				$password = $jsonObj->password;

				// 验证verifyCode
				$sessionCode = strtolower($session->get('verifyCode'));
				$session->del('verifyCode');
				if($verifyCode != $sessionCode){
					returnAjaxJson(400, "验证码错误！", null);
				}

				// 验证用户名和密码
				$db->query("select 
								id,
								name,
								type,
								password
							from admin_user 
							where 
								name=:name and 
								flag=1",
					array(
						"name"=>$name
						));
				$result = $db->prepare->fetchAll();
				if($result){
					if($result[0]["password"] != $password){
						returnAjaxJson(400, "登录失败，用户密码错误！", null);
					}
					$userId = $result[0]["id"];
					$userName = $result[0]["name"];
					$userType = $result[0]["type"];
					$token = sha1($userId . time());
					$now = strtotime(date('Y-m-d H:i:s'));

					// 判断是否是单点登录
					if($databaseInfo["singleLogin"]){
						$this->singleLogin($userId, $token, $now);
					}
					
					//保存用户session信息
					$session->set("userId", $userId);
					$session->set("userName", $userName);
					$session->set("userType", $userType);
					$session->set("userToken", $token);
					$session->set("loginTime", $now);

					// 更新最后一次登录时间
					$this->updateLoginTime($now, $userId);

					returnAjaxJson(200, "登录成功，请继续操作！", array("token"=>$token,"name"=>$userName));
				} else {
					returnAjaxJson(400, "登录失败，用户名错误或者未启用！", null);
				}
			}
		}

		// 退出登录
		public function loginOut($model, $action){
			global $db;
			if(($model=="login") && ($action=="loginout")){
				$this->removeSessionAndAdminLgin();
				returnAjaxJson(200, "退出登录成功！", null);
			}
		}

		// 是否登录
		public function isLogin(){
			global $session, $databaseInfo, $db;
			// 验证session
			if(!$session->get("userToken") || !$session->get("loginTime")){
				returnAjaxJson(100, "您未登录，请登录！", null);
			}
			// 验证session中loginTime是否超过10分钟
			$now = strtotime(date('Y-m-d H:i:s'));
			if(array_key_exists("HTTP_TOKEN", $_SERVER) && !($_SERVER['HTTP_TOKEN'] =='') && !($_SERVER['HTTP_TOKEN'] =='null')){
				$token = $_SERVER["HTTP_TOKEN"];
				if(($now - $session->get("loginTime")) > $databaseInfo["expiryTime"]){
					$this->removeSessionAndAdminLgin();
					returnAjaxJson(100, "您的登录已过期，请重新登录！", null);
				}
				// 验证session中token
				if($token != $session->get("userToken")){
					$this->removeSessionAndAdminLgin();
					returnAjaxJson(100, "验证登录操作失败！请重新登录", null);
				}

				// 更新session中loginTime值
				$session->set("loginTime", $now);
				
				// 是否单点登录
				if($databaseInfo["singleLogin"]){
					$this->updateAdminLoginTime($now);
				}
			} else{
				$this->removeSessionAndAdminLgin();
				returnAjaxJson(100, "验证登录操作失败！请重新登录", null);
			}
		}

		// 单点登录
		private function singleLogin($userId, $token, $now){
			global $db, $databaseInfo;
			// 更新admin_login表
			// 事务开始
			$db->PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
			$db->PDO->beginTransaction();

			$db->query("select
							login_time 
						from admin_login 
						where 
							user_id=:id 
						for update",
				array(
					"id"=>$userId
					));
			$result = $db->prepare->fetchAll();
			// 这个账号已经有登录
			if($result){
				$lastLoginTime = strtotime($result[0]["login_time"]);
				if(($now - $lastLoginTime) < $databaseInfo["expiryTime"]){
					// 登录未超时
					returnAjaxJson(400, "此账号在别的地方已经登录，不可以重复登录！", null);
				} else {
					// 登录已超时
					$db->query("update admin_login 
								set 
									login_time=:loginTime,
									token=:token 
								where 
									user_id=:id",
						array(
							"id"=>$userId,
							"loginTime"=>date("Y-m-d H:i:s", $now),
							"token"=>$token
							));
					if(!$db->prepare->rowCount()){
						$db->PDO->rollBack();
						returnAjaxJson(404, "登录失败，请重新登录！", null);
					}
				}
			} else {
				// 这个账号还没有登录
				$db->query("insert into admin_login(
								user_id,
								token)
							values(
								:id,
								:token)",
					array(
						"id"=>$userId,
						"token"=>$token
						));
				if(!$db->prepare->rowCount()){
					$db->PDO->rollBack();
					returnAjaxJson(404, "登录失败，请重新登录！", null);
				}
			}
			$db->PDO->commit();
			// 事务结束
		}

		// 单点登录更新adminLogin表中login_time字段
		private function updateAdminLoginTime($now){
			global $db, $session;
			$userId = $session->get("userId");
			// 更新admin_login表
			// 事务开始
			$db->PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
			$db->PDO->beginTransaction();

			$db->query("select login_time
						from admin_login
						where 
							user_id=:userid 
						for update",
				array(
					"userid"=>$userId
					));
			$result = $db->prepare->fetchAll();
			// 存在数据
			if($result){
				$db->query("update admin_login
							set
								login_time=:now 
							where
								user_id=:userid",
					array(
						"userid"=>$userId,
						"now"=>date("Y-m-d H:i:s", $now)
						));
					if(!$db->prepare->rowCount()){
						$db->PDO->rollBack();
						return ;
					}
			}
			$db->PDO->commit();
			// 事务结束
		}

		// 删除admin_login表对应账户的数据
		private function delAmdminLogin(){
			global $session, $db;
			$userId = $session->get("userId");
			if($userId){
				$db->query("delete from admin_login
							where
								user_id=:id", 
							array(
								"id"=>$session->get("userId")
				));
			}
		}

		// 退出登录
		private function removeSessionAndAdminLgin(){
			global $databaseInfo, $session;
			// 单点登录删除admin_login对应的账户数据
			if($databaseInfo["singleLogin"]){
				$this->delAmdminLogin();
			}

			// 注销session
			$session->destroy();
		}

		// 更新最近登录时间记录
		private function updateLoginTime($now, $userId){
			global $db;
			$db->query("update admin_user 
						set 
							last_login_time=:now 
						where 
							id=:userId",
						array(
							"now"=>date("Y-m-d H:i:s", $now),
							"userId"=>$userId
							)
						);
		}
	}
?>